
/**
 *
 */
package com.serviceprovider.business.module.admin.transaction.utility;

//~--- JDK imports ------------------------------------------------------------

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import java.text.SimpleDateFormat;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author mrduongnv@gmail.com
 */
public class StringUtils {

    /**
     * Instantiates a new string utils.
     */
    public StringUtils() {

        // this cannot be instantiated
    }

    /**
     * Checks if is contains digits.
     *
     * @param value
     *            the value
     * @return true, if is contains digits
     */
    public static boolean isContainsDigits(String value) {
        if (!isEmpty(value)) {
            for (int i = 0; i < value.length(); i++) {
                if (Character.isDigit(value.charAt(i))) {
                    return true;
                }
            }

            return false;
        }

        return false;
    }

    /**
     * Checks if is all digits.
     *
     * @param value
     *            the value
     * @return true, if is all digits
     */
    public static boolean isAllDigits(String value) {
        if (!isEmpty(value)) {
            for (int i = 0; i < value.length(); i++) {
                if (!Character.isDigit(value.charAt(i))) {
                    return false;
                }
            }

            return true;
        }

        return false;
    }

    /**
     * Checks if is credit or debit.
     *
     * @param value
     *            the value
     * @return true, if is credit or debit
     */
    public static boolean isCreditOrDebit(String value) {
        String  dot       = ".";
        boolean singleDot = true;

        if (!isEmpty(value)) {
            for (int i = 0; i < value.length(); i++) {
                if (!Character.isDigit(value.charAt(i))) {
                    if (!dot.equals(Character.toString(value.charAt(i)))) {
                        return false;
                    }

                    if (!singleDot) {
                        return false;
                    }

                    singleDot = false;
                }
            }

            return true;
        }

        return false;
    }

    /**
     * Checks if is empty.
     *
     * @param string
     *            the string
     * @return true, if is empty
     */
    public static boolean isEmpty(String string) {
        return ((string == null) || (string.trim().length() == 0));
    }

    /**
     * Extract SSN and originator code from identification number.
     *
     * @return the map
     */
    public static Map<String, String> extractOriginatorCodeAndSSN(String identificationNumber) {
        StringBuilder ssn            = new StringBuilder();
        StringBuilder originatorCode = new StringBuilder();

        if (isEmpty(identificationNumber)) {
            return null;
        }

        for (int i = 0; i < identificationNumber.length(); i++) {
            final char character = identificationNumber.charAt(i);

            if (!Character.isDigit(character)) {
                if (ssn.length() == 0) {
                    return null;
                }

                originatorCode.append(character);
            } else {
                if (originatorCode.length() != 0) {
                    return null;
                }

                ssn.append(character);
            }
        }

        Map<String, String> map = new LinkedHashMap<String, String>();

        map.put("ssn", ssn.toString());
        map.put("originatorCode", originatorCode.toString().trim());

        return map;
    }

    /**
     * Construct to string.
     *
     * @param object
     *            the object
     * @return the string
     */
    public static String constructToString(Object object) {
        try {
            return constructToStringWithBlacklist(object, null);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * Construct to string.
     *
     * @param object
     *            the object
     * @param blacklist
     *            the blacklist
     * @return the string
     */
    public static String constructToString(Object object, List<String> blacklist) {
        try {
            return constructToStringWithBlacklist(object, blacklist);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * Construct to string with blacklist.
     *
     * @param object
     *            the object
     * @param blacklist
     *            the blacklist
     * @return the string
     *
     */
    private static String constructToStringWithBlacklist(Object object, List<String> blacklist) {
        try {
            StringBuilder        builder             = new StringBuilder();
            Class                cls                 = object.getClass();
            BeanInfo             beanInfo            = Introspector.getBeanInfo(cls);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

            builder.append(cls.getName());
            builder.append(" [");

            for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
                if (propertyDescriptor.getWriteMethod() == null) {
                    continue;
                }

                if ((blacklist == null) || blacklist.isEmpty()
                        ||!blacklist.contains(propertyDescriptor.getDisplayName())) {
                    constructToStringProperty(object, propertyDescriptor.getDisplayName(), builder);
                }
            }

            builder.append("\n]");

            return builder.toString();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * Construct to string property.
     *
     * @param object
     *            the object
     * @param property
     *            the property
     * @param builder
     *            the string builder
     * @throws IntrospectionException
     *             the introspection exception
     * @throws InstantiationException
     *             the instantiation exception
     * @throws IllegalAccessException
     *             the illegal access exception
     * @throws IllegalArgumentException
     *             the illegal argument exception
     * @throws InvocationTargetException
     *             the invocation target exception
     * @return string
     */
    private static String constructToStringProperty(Object object, String property, StringBuilder builder)
            throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        Class              cls        = object.getClass();
        PropertyDescriptor descriptor = new PropertyDescriptor(property, cls);

        return invoke(cls, property, descriptor, object, builder);
    }

    /**
     * Invoke.
     *
     * @param cls
     *            the cls
     * @param property
     *            the property
     * @param descriptor
     *            the descriptor
     * @param arg
     *            the arg
     * @param builder
     *            the string builder
     * @return string
     * @throws IllegalAccessException
     *             the illegal access exception
     * @throws InvocationTargetException
     *             the invocation target exception
     */
    private static String invoke(Class cls, String property, PropertyDescriptor descriptor, Object arg,
                                 StringBuilder builder)
            throws IllegalAccessException, InvocationTargetException {
        Method readMethod    = descriptor.getReadMethod();
        Object propertyValue = readMethod.invoke(arg);

        builder.append("\n");
        builder.append("\t" + property);
        builder.append("=");
        builder.append(propertyValue);

        return builder.toString();
    }

    public static String makeFieldReadable(String value) {
        if (isEmpty(value)) {
            return "";
        }

        StringBuilder builder = new StringBuilder();

        for (int i = 0; i < value.length(); i++) {
            final char character = value.charAt(i);

            if (i == 0) {
                builder.append(Character.toUpperCase(character));
            } else {
                if (Character.isUpperCase(character)) {
                    builder.append(" ");
                }

                builder.append(character);
            }
        }

        return builder.toString();
    }

    /**
     * Make first letter capital.
     *
     * @param value
     *            the value
     * @return the string
     */
    public static String makeFirstLetterCapital(String value) {
        if (isEmpty(value)) {
            return "";
        }

        StringBuilder builder = new StringBuilder();

        for (int i = 0; i < value.length(); i++) {
            final char character = value.charAt(i);

            if (i == 0) {
                builder.append(Character.toUpperCase(character));
            } else {
                builder.append(character);
            }
        }

        return builder.toString();
    }

    /**
     * Format date.
     *
     * @param date
     *            the date
     * @return the string
     */
    public static String formatDate(Date date) {
        if (date == null) {
            return null;
        }

        String           pattern = "MM/dd/yyyy";
        SimpleDateFormat format  = new SimpleDateFormat(pattern);

        try {
            return format.format(date);
        } catch (Exception e) {
            return "-1";
        }
    }
}



